home *** CD-ROM | disk | FTP | other *** search
- TITLE FASTPLOT.ASM
- COMMENT *
- This program reads both ASCII and binary files from any disk drive of
- any IBM/PC/XT or clone. It sends the file contents to the 'COM' port
- while maintaining several different handshake protocols. The most common
- protocol uses clear to send (CTS, pin 4 of the DB25 connector) to signal
- the host when to start/stop sending data. The next most common protocol
- uses data set ready (DSR, pin 20 of the DB25 connector) to signal the
- host in the same manner. The last method uses X-ON/X-OFF protocol in which
- the device sends the host a byte (^S or ^Q) which is used to start/stop
- the data flow from the host. All three protocols are supported in this
- program. *
- ;
- ; Created 30-DEC-86 Richard B. Johnson
- ; Modification record:
- ; 04-JAN-86 Added multiple port routines to address 5 COM ports. :RBJ
- ; 06-JAN-86 Added routine to check for invalid COM port. Checks to
- ; see if the required UART (8250) is present. For speed,
- ; this process 'talks' directly to the UART so it's type
- ; must be known for the routines to work. :RBJ
- ;
- CR EQU 0DH
- LF EQU 0AH
- BEL EQU 07H
- COL_LEN EQU 60 ;100 PERCENT OF THE COLUMN
- DTA EQU 80H ;DEFAULT DATA TRANSFER AREA
- MS_DOS EQU 21H ;SYSTEM CALLS
- KBD EQU 16H ;KEYBOARD ROM VECTOR
- VID_ROM EQU 10H ;VIDEO ROM VECTOR
- X_ON EQU 'Q'-64 ;PROTOCOL BYTES
- X_OFF EQU 'S'-64
- CTL_C EQU 'C'-64
- ; 8250 UART EQUATES
- LSTAT EQU 5 ;OFFSET TO LINE STATUS REGISTER
- MSTAT EQU 6 ;OFFSET TO MODEM STATUS REGISTER
- CTS EQU 00010000B ;CLEAR TO SEND
- DSR EQU 00100000B ;DATA SET READY
- DR EQU 00000001B ;DATA READY
- THRE EQU 00100000B ;TRANSMITTER HOLDING REGISTER READY
- BIOS_DATA_SEG EQU 40H ;ROM DATA SEGMENT
- ;
- FILE_BUF STRUC ;DTA STRUCTURE AFTER A 'FIND FIRST' CALL
- RES DB 21 DUP (?) ;RESERVED
- ATTR DB ? ;FILE ATTRIBUTE FOUND
- TIME DW ? ;TIME FILE CREATED
- DATE DW ? ;DATE FILE CREATED
- SIZEL DW ? ;LOW WORD OF THE FILE SIZE
- SIZEH DW ? ;HIGH WORD OF THE FILE SIZE
- NAMEF DB ? ;FOUND FILENAME
- FILE_BUF ENDS
- ;
- IF1
- %OUT [PASS1]
- ELSE
- %OUT [PASS2]
- ENDIF
- ;
- PSEG SEGMENT PARA
- ASSUME CS:PSEG, DS:PSEG, ES:PSEG, SS:PSEG
- ORG 100H ;'.COM' FILE
- MAIN PROC NEAR
- JMP SHORT BEGIN
- DB 'Copyright (C) 1986, 1987 Richard B. Johnson '
- BEGIN: CLD
- CLI
- MOV AX,CS
- MOV DS,AX ;SEGMENT FIXUPS (MS_DOS SHOULD DO IT)
- MOV ES,AX
- MOV SS,AX
- MOV SP,OFFSET STACK ;PUT IT WHERE WE CAN KEEP TRACK
- STI
- CALL CLS ;CLEAR THE SCREEN
- CALL SAV_CUR ;GET CURSOR TYPE
- MOV WORD PTR [CURSORT],CX ;SAVE TYPE
- CALL GET_CMD ;GET TYPED COMMAND LINE
- CALL OPENF ;ATTEMPT TO OPEN THE FILE
- JNC OPNOK ;GOOD OPEN
- PUSH SI ;SAVE FILENAME
- MOV SI,OFFSET NOFILE ;POINT TO 'NO FILE'
- CALL PNUL ;PRINT TO SCREEN
- POP SI ;RESTORE FILENAME
- CALL PNUL ;PRINT TO SCREEN
- MOV SI,OFFSET CRLF ;END OF LINE
- CALL PNUL ;PRINT TOO
- JMP FINIS ;AND EXIT
- OPNOK: MOV DH,6 ;SEVENTH LINE
- MOV DL,CNTR
- CALL POS_CUR ;SET CURSOR POSITION
- MOV SI,OFFSET DIAL ;POINT TO THE SIRING
- CALL PNUL ;WRITE TO SCREEN
- INC DH ;NEXT LINE
- CALL POS_CUR ;SET CURSOR
- MOV SI,OFFSET DIAL1 ;POINT TO NEXT LINE OF TEXT
- CALL PNUL ;PRINT TO SCREEN
- INC DH ;READY NEXT LINE
- CALL POS_CUR ;SET CURSOR THERE
- MOV SI,OFFSET DIAL2 ;POINT TO 'RULER'
- CALL PNUL ;PRINT TO SCREEN
- MOV WORD PTR [RULER],DX ;SAVE THAT LOCATION
- CALL GET_SIZE ;GET FILE SIZE
- MOV DX,WORD PTR [FINAL_H] ;READY FOR DIVIDE
- MOV AX,WORD PTR [FINAL_L] ;GET FINAL NUMBER
- MOV BX,COL_LEN ;GET LENGTH OF THE SCALE
- MOV WORD PTR [RUN_BX],BX ;GET WRITES TO SCREEN
- DIV BX ;AX= NUMBER OF ITERATIONS
- MOV WORD PTR [WMASKL],AX ;SAVE IN MEMORY
- MOV DX,WORD PTR [RULER] ;GET 'HOME' LOCATION
- ADD DH,5 ;FIVE LINES
- CALL POS_CUR ;PUT CURSOR THERE
- MOV SI,OFFSET READY ;POINT TO 'GET' PLOTTER READY
- CALL PNUL ;PRINT TO THE SCREEN
- PAUSE: CALL KEY ;WAIT FOR RESPONSE
- JZ PAUSE ;CONTUNUE TO LOOP
- CMP AL,CTL_C ;SEE IF AN ABORT
- JNZ GO ;NOPE
- CALL CLOSEF ;YES, CLOSE THE FILE
- MOV SI,OFFSET ABORTED ;POINT TO THE STRING
- CALL PNUL ;PRINT TO SCREEN
- JMP FINIS ;EXIT
- GO: CALL KILL_CUR ;KILL THE CURSOR
- MOV DX,WORD PTR [RULER] ;GET 'HOME' POSITION
- ADD DH,5 ;ADD FIVE LINES
- CALL POS_CUR ;PUT CURSOR THERE
- MOV SI,OFFSET WORKING ;POINT TO THE PROMPT STRING
- CALL PNUL ;PRINT TO THE SCREEN
- CONT: CALL STATUS ;SHOW OUTPUT BYTE COUNT
- CALL READF ;READ THE FILE
- TEST AX,AX ;ANY BYTES READ?
- JNZ OUTPUT ;YES
- CALL CLOSEF ;NO, CLOSE THE FILE
- MOV SI,OFFSET DONE ;POINT TO 'END OF FILE'
- CALL PNUL ;PRINT TO THE SCREEN
- JMP FINIS ;AND EXIT
- OUTPUT: MOV CX,AX ;BYTE COUNT
- MOV SI,OFFSET BUFFER ;WHERE THE DATA IS
- CALL COMOUT ;OUTPUT TO THE SELECTED COM PORT
- JMP SHORT CONT ;AND CONTINUE
- MAIN ENDP
- ;
- ; Get communications port address. BX= index into table.
- ; Check to see if adapter is present. Report errors and exit if unavailable.
- ;
- GET_PORT PROC NEAR
- PUSH DS ;SAVE DATA SEGMENT
- MOV AX,BIOS_DATA_SEG ;WHERE THE BIOS KEEPS ADDRESSES
- MOV DS,AX ;FIRST PAGE
- MOV DX,WORD PTR [BX] ;GET COM PORT LOCATION
- POP DS ;RESTORE SEGMENT
- MOV WORD PTR [PORT],DX ;SAVE IN LOCAL AREA
- ADD DX,2 ;OFFSET TO INTERRUPT IDENT REGIS
- IN AL,DX ;GET STATUS
- TEST AL,11111000B ;CHECK FOR AN 8250 UART
- JZ MAYBE ;COULD BE A REAL UART
- NOUART: MOV SI,OFFSET BADUART ;NOT AN 8250 UART
- CALL PNUL ;PRINT TO SCREEN
- SHR BX,1 ;DIVIDE BY TWO (RESTORE BIAS)
- MOV AL,BL
- ADD AL,'0'+1 ;RESTORE BIAS
- CALL CON_OUT ;OUTPUT THE BYTE
- MOV SI,OFFSET NFIND ;POINT TO STRING
- CALL PNUL ;PRINT TO SCREEN
- JMP FINIS ;EXIT
- MAYBE: ADD DX,3 ;OFFSET TO LINE STATUS REGISTER
- MOV CX,-1 ;TEMP TIMER
- RESPON: IN AL,DX ;GET UART STATUS
- TEST AL,THRE ;SEE IF TX SHIFT REGIS EMPTY
- JNZ UARTOK ;YES, PERHAPS A UART AFTER ALL
- LOOP RESPON ;WAIT A BIT
- JMP SHORT NOUART
- UARTOK: RET
- GET_PORT ENDP
- ;
- ; Print string addressed by SI until a null.
- ;
- PNUL PROC NEAR
- LODSB ;GET A BYTE
- TEST AL,AL ;IS IT A NULL?
- JZ PDONE ;YES, DONE
- CALL CON_OUT ;NO, SEND IT OUT
- JMP SHORT PNUL ;CONTINUE
- PDONE: RET
- PNUL ENDP
- ;
- ; Parse the command line. Print 'HELP' if command line is not present or isn't
- ; correct.
- ;
- GET_CMD PROC NEAR
- MOV SI,DTA ;COMMAND LINE BUFFER
- LODSB ;GET BYTES TYPED
- TEST AL,AL ;CHECK FOR NOTHING
- JZ NOWAY ;NO COMMAND LINE
- CBW
- MOV BX,AX ;NEED AN INDEX REGISTER
- MOV BYTE PTR [SI+BX],0 ;THIS WILL BE THE END OF FILENAME
- INC SI ;GET BY THE SPACE
- LODSB ;GET PROTOCOL
- AND AL,95 ;CONVERT TO UPPER CASE
- MOV BYTE PTR [PROTO],CTS ;ASSUME CLEAR TO SEND
- CMP AL,'C' ;CORRECT?
- JZ WASOK ;YES
- MOV BYTE PTR [PROTO],DSR ;ASSUME DATA SET READY
- CMP AL,'D' ;CORRECT?
- JZ WASOK ;YES
- MOV BYTE PTR [PROTO],0FFH ;ASSUME X-ON/X-OFF
- CMP AL,'X' ;IS IT XON/XOFF?
- JZ WASOK ;YES
- NOWAY: MOV SI,OFFSET HELP ;NONE OF ABOVE, PRINT HELP
- CALL PNUL ;PRINT TO SCREEN
- JMP FINIS ;EXIT
- WASOK: LODSB ;GET NEXT BYTE
- MOV CX,BX ;SAVE INDEX
- XOR BX,BX ;ASSUME COM PORT 1
- CMP AL,' ' ;WAS IT A SPACE?
- JZ USE1 ;WAS JUST A SPACE
- SUB AL,'0'+1 ;SUBTRACT ASCII BIAS
- JC NOWAY ;NOT A CORRECT PORT NUMBER
- CMP AL,5 ;FOUR PORTS MAX
- JNC NOWAY ;TOO HIGH A PORT NUMBER
- MOV BL,AL ;USE AS AN INDEX
- INC SI ;FILENAME FOLLOWS
- USE1: MOV WORD PTR [FNAME],SI ;SAVE FILENAME ADDRESS
- ADD BX,BX ;TIMES TWO
- CALL GET_PORT
- MOV BX,CX ;RESTORE INDEX
- RET
- GET_CMD ENDP
- ;
- ; Output the buffer contents addressed by SI to the communications port
- ; respecting the various protocols.
- ;
- COMOUT PROC NEAR
- CMP BYTE PTR [PROTO],0FFH ;SEE IF X-ON/X-OFF
- JZ XON
- AGAIN: CALL CHECK ;CHECK FOR AN ABORT
- CALL MOD_STAT ;GET MODEM STATUS
- TEST AL,BYTE PTR [PROTO] ;SEE IF OK TO TRANSMIT
- JNZ NOWAIT ;YES, IT'S OK
- PUSH CX ;SAVE COUNT
- CALL SAV_CUR ;SAVE CURSOR POSITION
- PUSH SI ;SAVE LOCATION
- MOV SI,OFFSET SYNC ;POINT TO STRING
- MOV WORD PTR [LSPRP],SI ;SAVE FOR NOW
- CALL PNUL ;PRINT ON THE SCREEN
- POP SI ;RESTORE LOCATION
- CALL RES_CURP ;RESTORE CURSOR POSITION
- NOTYET: CALL CHECK ;CHECK FOR AN ABORT
- CALL MOD_STAT
- TEST AL,BYTE PTR [PROTO] ;SEE IF IT'S OK YET
- JZ NOTYET ;NOT YET
- CALL SAV_CUR ;SAVE CURSOR
- PUSH SI ;SAVE LOCATION
- MOV SI,OFFSET RESUME ;POINT TO THE STRING
- MOV WORD PTR [LSPRP],SI ;SAVE FOR NOW
- CALL PNUL ;PRINT TO SCREEN
- POP SI ;RESTORE LOCATION
- CALL RES_CURP ;RESTORE CURSOR POSITION
- POP CX ;RESTORE COUNT
- JMP SHORT NOWAIT ;OK TO CONTINUE
- ;
- XON: CALL CHECK ;CHECK WAIT/ABORT FROM CONSOLE
- CALL COMIN ;CHECK INPUT PORT
- JZ NOWAIT ;NOTHING HERE YET
- CMP AL,X_OFF ;WANT TO WAIT
- JNZ NOWAIT ;NOPE, MUST BE GARBAGE
- CALL WAITX ;YES, WAIT FOR X_ON
- NOWAIT: CALL BYTOUT ;OUTPUT THE BYTE
- LOOP COMOUT ;CONTINUE
- RET
- COMOUT ENDP
- ;
- ; Get any possible byte from the 'COM' port.
- ;
- COMIN PROC NEAR
- MOV DX,WORD PTR [PORT] ;GET COM PORT ADDRESS
- PUSH DX ;SAVE FOR NOW
- ADD DX,LSTAT ;ADD IN OFFSET TO LINE STATUS
- IN AL,DX ;GET STATUS BYTE
- POP DX ;RESTORE BASE PORT ADDRESS
- TEST AL,DR ;SEE IF DATA READY
- JZ NODAT ;WAIT FOREVER UNTIL READY
- IN AL,DX ;GET BYTE
- INC DX ;MAKE CERTAIN NO ZERO
- NODAT: RET
- COMIN ENDP
- ;
- ; Check the modem status of the UART.
- ;
- MOD_STAT PROC NEAR
- MOV DX,WORD PTR [PORT] ;GET PORT ADDRESS
- ADD DX,MSTAT ;ADD IN OFFSET TO MODEM STATUS
- IN AL,DX ;GET STATUS BYTE
- RET
- MOD_STAT ENDP
- ;
- ; Output a byte from the buffer addressed by SI to the 'COM1' UART.
- ;
- BYTOUT PROC NEAR
- MOV DX,WORD PTR [PORT] ;GET COM PORT ADDRESS
- PUSH DX ;SAVE FOR NOW
- ADD DX,LSTAT ;ADD IN OFFSET TO LINE STATUS
- FOREVER:
- IN AL,DX ;GET STATUS BYTE
- TEST AL,THRE ;WAIT FOR HOLDING REGISTER EMPTY
- JNZ EMPTY ;WAIT UNTIL READY
- CALL STATUS ;UART NOT READY, SHOW STATUS
- JMP SHORT FOREVER ;CONTINUE
- EMPTY: POP DX ;RESTORE BASE PORT ADDRESS
- LODSB ;GET BYTE FROM BUFFER
- OUT DX,AL ;AND OUTPUT THE BYTE
- INC WORD PTR [XMITL] ;UP THE BYTE COUNT
- JNZ BYPASS ;NO OVERFLOW
- INC WORD PTR [XMITH] ;UPDATE THE COUNT
- BYPASS: CALL SCALE
- RET
- BYTOUT ENDP
- ;
- ; Wait for the host to send a X-ON. Abort from the keyboard is possible.
- ;
- WAITX PROC NEAR ;WAIT FOR X-ON FROM HOST
- PUSH SI ;SAVE LOCATION
- PUSH CX ;SAVE COUNT
- CALL SAV_CUR ;SAVE CURSOR POSITION
- MOV SI,OFFSET SYNC ;POINT TO STRING
- MOV WORD PTR [LSPRP],SI ;SAVE FOR NOW
- CALL PNUL ;PRINT TO SCREEN
- CALL RES_CURP ;RESTORE CURSOR POSITION
- WAIT0: CALL CHECK ;CHECK FOR ABORT
- CALL COMIN ;GET INPUT BYTE
- CMP AL,X_ON ;READY TO RESUME?
- JNZ WAIT0 ;NOPE
- CALL SAV_CUR ;SAVE CURSOR POSITION
- MOV SI,OFFSET RESUME ;POINT TO STRING
- MOV WORD PTR [LSPRP],SI ;SAVE FOR NOW
- CALL PNUL ;PRINT TO SCREEN
- CALL RES_CURP ;RESTORE THE CURSOR POSITION
- POP CX ;RESTORE COUNT
- POP SI ;RESTORE LOCATION
- RET
- WAITX ENDP
- ;
- ; Check for a possible abort from the keyboard. Pause for a second key
- ; pressed if there is any keyboard input.
- ;
- CHECK PROC NEAR
- PUSH SI ;SAVE LOCATION
- PUSH CX ;SAVE COUNT
- CALL KEY ;CHECK FOR A KEY PRESSED
- JZ NOKEY ;NO KEY WAS PRESSED
- CMP AL,CTL_C ;CHECK FOR CONTROL C
- JZ QUIT ;WAS CONTROL C
- CALL SAV_CUR ;SAVE CURRENT CURSOR POSITION
- MOV SI,OFFSET HOLDING ;POINT TO STRING
- CALL PNUL ;PRINT IT
- CALL RES_CURP ;RESTORE THE CURSOR POSITION
- HOLD PROC NEAR ;WAIT FOR A KEY TO BE PRESSED
- CALL KEY ;CHECK KEYBOARD
- JZ HOLD ;NOTHING PRESSED
- CMP AL,CTL_C ;CHECK FOR CONTROL C
- JZ QUIT ;ABORT
- MOV SI,WORD PTR [LSPRP] ;GET LAST STRING
- CALL PNUL ;PRINT IT
- CALL RES_CURP ;RESTORE CURSOR POSITION
- NOKEY: POP CX ;RESTORE COUNT
- POP SI ;RESTORE LOCATION
- RET ;END OF HOLD
- QUIT: POP CX ;LEVEL STACK CX=COUNT
- POP SI ;BUFFER LOCATION
- POP AX ;RETURN ADDRESS
- MOV SI,OFFSET ABORTED
- CALL PNUL
- JMP FINIS
- HOLD ENDP
- CHECK ENDP
- ;
- ; Get any input from the keyboard.
- ;
- KEY PROC NEAR
- MOV AH,1 ;CHECK IF CHARACTER WAITING
- INT KBD
- JZ NOPE ;NOTHING HERE
- MOV AH,0 ;YES, GET THE CHARACTER
- INT KBD
- TEST AX,AX ;INSURE NO ZERO FLAG
- NOPE: RET
- KEY ENDP
- ;
- ; Print transmit status to the screen.
- ;
- STATUS PROC NEAR
- PUSH SI ;SAVE INDEX, DESTROYED BY ASCII
- PUSH DX ;SAVE ALSO
- PUSH CX
- CALL SAV_CUR
- MOV DX,WORD PTR [XMITH] ;GET HIGH WORD OF BYTES TRANSMITTED
- MOV AX,WORD PTR [XMITL] ;GET LOW WORD OF BYTES TRANSMITTED
- CALL ASCII
- CALL RES_CURP ;RESTORE CURSOR POSITION
- POP CX
- POP DX
- POP SI
- RET
- STATUS ENDP
- ;
- ; Open the file pointed to by [FNAME]
- ;
- OPENF PROC NEAR
- MOV DX,WORD PTR [FNAME] ;POINT TO FILENAME
- XOR CX,CX ;NORMAL FILE
- MOV AX,3D00H ;OPEN FOR READING
- INT MS_DOS
- MOV WORD PTR [HANDLE],AX ;SAVE THE HANDLE
- JNC FOUND ;FILE WAS FOUND
- MOV BYTE PTR [SI+BX-2],0 ;FOR A BAD FILENAME
- RET
- FOUND: MOV AH,4EH ;GET FILE CHARACTERISTICS
- INT MS_DOS ;WILL RETURN IN DTA [80H]
- RET
- OPENF ENDP
- ;
- ; Close the file.
- ;
- CLOSEF PROC NEAR
- MOV AX,3E00H ;CLOSE FILE FUNCTION
- MOV BX,WORD PTR [HANDLE] ;GET THE FILE HANDLE
- INT MS_DOS
- RET
- CLOSEF ENDP
- ;
- ; Read the file. Read as much into memory as possible within the 64k
- ; segment allowed to speed file access. For most files, only one read
- ; will be required.
- ;
- READF PROC NEAR
- MOV DX,OFFSET BUFFER ;WHERE TO PUT FILE DATA
- MOV CX,-1 ;64 K TO READ
- SUB CX,DX ;MINUS SPACE USED FOR PROGRAM
- MOV BX,WORD PTR [HANDLE] ;GET FILE HANDLE
- MOV AX,3F00H ;READ THE FILE
- INT MS_DOS
- RET
- READF ENDP
- ;
- ; End the program, return to MS_DOS. Return status OK even if aborted.
- ;
- FINIS PROC NEAR
- CALL RES_CUR ;RESTORE CURSOR TYPE
- MOV DH,23 ;24TH LINE
- MOV DL,0 ;FIRST COLUMN
- CALL POS_CUR ;CURSOR AT BOTTOM OF SCREEN
- MOV AX,4C00H
- INT MS_DOS
- FINIS ENDP
- ;
- GET_SIZE PROC NEAR
- MOV DX,WORD PTR [RULER]
- ADD DH,2 ;TWO LINES
- CALL POS_CUR ;PUT CURSOR THERE
- MOV SI,OFFSET HOWBIG
- CALL PNUL
- MOV SI,DTA + NAMEF ;POINT TO THE FILENAME
- CALL PNUL
- MOV SI,OFFSET IS
- CALL PNUL
- MOV SI,DTA
- MOV DX,WORD PTR [SI+ SIZEH] ;GET PART OF FILE SIZE
- MOV AX,WORD PTR [SI+ SIZEL] ;GET LOW PART OF FILE SIZE
- MOV WORD PTR [FINAL_L],AX
- MOV WORD PTR [FINAL_H],DX
- CALL ASCII
- MOV SI,OFFSET LONG
- CALL PNUL
- RET
- GET_SIZE ENDP
- ;
- ; Print double precision number in DX:AX
- ;
- ASCII PROC NEAR
- MOV SI,0000 ;LEADING ZERO FLAG
- MOV CX,3B9AH ;GET BILLIONS
- MOV BX,0CA00H
- CALL SUBTR ;SUBTRACT THEM OUT
- CALL COMMA ;PUT IN A COMMA
- MOV CX,05F5H ;GET HUNDRED-MILLIONS
- MOV BX,0E100H
- CALL SUBTR ;SUBTRACT THEM OUT
- MOV CX,0098H ;GET TEN-MILLIONS
- MOV BX,9680H
- CALL SUBTR ;SUBTRACT THEM OUT
- MOV CX,000FH ;GET MILLIONS
- MOV BX,4240H
- CALL SUBTR ;SUBTRACT THEM OUT
- CALL COMMA ;PUT IN A COMMA
- MOV CX,0001H ;GET HUNDRED-THOUSANDS
- MOV BX,86A0H
- CALL SUBTR ;SUNTRACT THEM OUT
- MOV CX,0000H ;GET TEN-THOUSANDS
- MOV BX,2710H
- CALL SUBTR ;SUBTRACT THEM OUT
- MOV CX,0000H ;GET THOUSANDS
- MOV BX,03E8H
- CALL SUBTR ;SUNTRACT THEM OUT
- CALL COMMA ;PUT IN A COMMA
- MOV CX,0000H ;GET HUNDREDS
- MOV BX,0064H
- CALL SUBTR ;SUBTRACT THEM OUT
- MOV CX,0000H ;GET TENS
- MOV BX,000AH
- CALL SUBTR ;SUBTRACT THEM OUT
- ADD AL,'0'
- JMP SHORT CON_OUT ;IMPLIED RETURN
- ;
- SUBTR: MOV DI,'0'-1 ;START WITH ONE LESS THAN ASCII BIAS
- SUBTR1: INC DI ;COUNTER
- SUB AX,BX ;DWORD SUBTRACTION
- SBB DX,CX
- JNB SUBTR1 ;CONTINUE UNTIL CARRY
- ADD AX,BX ;ONE TOO MANY, ADD BACK
- ADC DX,CX
- PUSH AX ;SAVE FOR NOW
- MOV AX,DI ;GET COUNT
- CMP SI,0 ;SEE IF ANY BYTES HAVE BEEN PRINTED
- JNZ SUBTR2 ;NO, CAN'T BE A LEADING ZERO
- CMP AL,'0' ;IS IS A ZERO?
- JZ SUBTR3 ;YES, DON'T PRINT LEADING ZEROS
- INC SI ;NO SET FLAG
- SUBTR2: CALL CON_OUT
- SUBTR3: POP AX
- RET
- ;
- COMMA: CMP SI,0 ;SEE IF ANY BYTES HAVE BEEN PRINTED
- JZ PASS ;NO, THEN NO COMMAS
- PUSH AX
- MOV AL,','
- CALL CON_OUT
- POP AX
- PASS: RET
- ASCII ENDP
- ;
- ; Using the 'faster than DOS' video ROM routine, output a byte to the screen.
- ;
- CON_OUT PROC NEAR
- PUSH BX
- PUSH DX
- ZERO: MOV AH,14 ;WRITE CHARACTER TO SCREEN,
- MOV BX,7 ;NORMAL ATTRIBUTE
- INT VID_ROM
- EXIT: POP DX
- POP BX
- RET
- CON_OUT ENDP
- ;
- SAV_CUR PROC NEAR
- MOV AH,3 ;GET CURSOR POSITION, TYPE
- MOV BH,0 ;PAGE ZERO
- INT VID_ROM
- MOV WORD PTR [CURSORP],DX ;SAVE POSITION
- RET
- SAV_CUR ENDP
- ;
- ; Kill the cursor by making it so tiny you can't see it!!
- ;
- KILL_CUR PROC NEAR
- MOV CX,-1
- MOV AH,1
- INT VID_ROM
- RET
- KILL_CUR ENDP
- ;
- RES_CUR PROC NEAR
- MOV AH,1
- MOV CX,WORD PTR [CURSORT] ;GET OLD CURSOR TYPE
- INT VID_ROM ;RESTORE THE CURSOR
- RET
- RES_CUR ENDP
- ;
- RES_CURP PROC NEAR
- MOV DX,WORD PTR [CURSORP] ;GET OLD CURSOR POSITION
- ;
- POS_CUR PROC NEAR ;PUT CURSOR AT DH=ROW, DL=COLUMN
- MOV AH,2
- MOV BH,0 ;PAGE ZERO
- INT VID_ROM
- RET
- POS_CUR ENDP
- RES_CURP ENDP
- ;
- ADVANCE PROC NEAR
- CALL SAV_CUR ;SAVE PRESENT POSITION
- MOV DX,WORD PTR [RULER] ;GET LAST 'RULER' POSITION
- INC WORD PTR [RULER] ;READY NEXT
- CALL POS_CUR ;PUT CURSOR AT LAST CHARACTER POS
- MOV AL,'=' ;COVER UP THE '>'
- CALL CON_OUT ;WRITE TO SCREEN
- MOV AL,'>' ;ADD AN ARROW
- CALL CON_OUT ;WRITE TO SCREEN
- CALL RES_CURP ;RESTORE CURSOR
- RET
- ADVANCE ENDP
- ;
- SCALE PROC NEAR
- PUSH CX ;SAVE COUNT
- DEC WORD PTR [RUN_BX]
- JNZ NOADV
- MOV AX,WORD PTR [WMASKL] ;GET NEW PARAMS
- MOV WORD PTR [RUN_BX],AX ;INTO THE 'INSIDE' RUNNING COUNT
- CALL ADVANCE ;ADVANCE THE POINTER
- NOADV: POP CX ;RESTORE BYTE COUNT
- RET
- SCALE ENDP
- ;
- CLS PROC NEAR
- MOV AX,0500H ;SELECT ACTIVE PAGE
- INT VID_ROM
- MOV AX,0600H ;SCROLL ACTIVE PAGE AWAY
- XOR CX,CX ;UPPER LEFT
- MOV BH,7 ;ATTRIBUTE
- MOV DH,24 ;25TH ROW
- MOV DL,79 ;80TH COLUMN
- INT VID_ROM
- MOV DH,1 ;SECOND LINE LINE FROM TOP
- MOV DL,CENTER ;WHATEVER CENTERS THE STRING
- CALL POS_CUR ;CURSOR HOME
- MOV SI,OFFSET LOGO ;POINT TO SIGNON
- CALL PNUL ;PRINT TO THE SCREEN
- MOV DX,0500H ;SIXTH LINE FROM TOP
- CALL POS_CUR ;CURSOR HOME
- RET
- CLS ENDP
- ;
- ; Data area.
- ;
- PROTO DB ? ;MASK BYTE FOR PROTOCOL
- EVEN
- HANDLE DW ? ;OPEN FILE HANDLE
- FNAME DW ? ;LOCATION OF THE FILENAME
- CURSORT DW ? ;SAVE CURSOR TYPE
- CURSORP DW ? ;SAVE CURSOR POSITION
- PORT DW ? ;COM PORT
- XMITH DW 0 ;NUMBER OF BYTES TRANSMITTED (HIGH WORD)
- XMITL DW 0 ;NUMBER OF BYTES TRANSMITTED (LOW WORD)
- LSPRP DW RESUME ;LAST STATUS WORD
- FINAL_L DW ? ;FINAL NUMBER
- FINAL_H DW ?
- RUN_BX DW ?
- WMASKL DW ?
- CURSOR DW ? ;SAVE CURSOR
- RULER DW ?
- ;
- DONE DB CR,LF,' The plot is finished.',CR,LF,BEL,0
- ABORTED DB CR,LF,' Aborted! ',CR,LF,BEL,0
- HOLDING DB CR,LF,' [Holding] ',0
- RESUME DB CR,LF,' ',0
- SYNC DB CR,LF,' [TTYSYNC]',0
- DB 16 DUP ('STACK ')
- STACK LABEL WORD
- ;
- ; From here on up to offset 64k is used for the file buffer. The data
- ; is overwritten since it's only used before the file is read into the
- ; buffer.
- ;
- BUFFER LABEL BYTE
- DIAL DB ' Percent completion',0
- DIAL1 DB '0 10 20 30 40 50 60 '
- DB '70 80 90 100',0
- DIAL2 DB 10 DUP ("+-----")
- DB "+"
- DB 0
- CNTR EQU (40 - ($ - DIAL2)/2)
- LOGO DB 'uDESIGNS IBM/PC/XT Plotter Driver',0
- CENTER EQU (40 - ($ - LOGO)/2)
- HOWBIG DB 'The plot file ',0
- IS DB ' is ',0
- LONG DB ' bytes in length.'
- CRLF DB CR,LF,0
- READY DB 'Hit any key when the plotter is ready: ',0
- WORKING DB ' '
- DB CR,LF,' Hit any key to pause.'
- DB CR,LF,' Hit any key to resume.'
- DB CR,LF,' Hit ^C to abort.'
- DB CR,LF,' Bytes transmitted: ',0
- BADUART DB CR,LF,' Communications adapter COM',0
- NFIND DB ': not present.'
- DB CR,LF,0
- NOFILE DB CR,LF,' File not found: ',0
- HELP DB CR,LF,'FASTPLOT [C,D,X]<PORT> [FILENAME]'
- DB CR,LF,'C = CLEAR TO SEND protocol (pin 4 of DB25 connector)'
- DB CR,LF,'D = DATASET READY protocol (pin 20 of DB25 connector)'
- DB CR,LF,'X = X-ON/X-OFF protocol'
- DB CR,LF,'PORT<OPTIONAL> = 1, 2, 3, 4 (Default is COM1:)'
- DB CR,LF,'FILENAME = any \PATH\FILENAME combination.'
- DB CR,LF,'Examples:'
- DB CR,LF,'Fastplot x orcad.plt'
- DB CR,LF,'Fastplot x2 orcad.plt'
- DB CR,LF,'Fastplot c2 orcad.plt'
- DB CR,LF,'Fastplot d4 c:\draft\orcad.plt'
- DB CR,LF,0
- PSEG ENDS
- END MAIN